/*
 * Dcm_UDS0x2F.c
 *
 *  Created on: 2018-8-1
 *      Author: tao.yu
 */
#include "UDS.h"


/****************************************************************
     UDS:InputOutputControlByIdentifier (2F hex) service
 ***************************************************************/
#if(STD_ON == DCM_UDS_SERVICE0X2F_ENABLED)


static FUNC(void, DCM_CODE)Dcm_UdsIOControlSendResponse(
        uint8     ProtocolCtrlId,
        uint8   MsgCtrlId,
        uint16  RecDid,
        uint16  Offset,
        uint16   ControlStatusRecordSize,
        uint8   InputOutControlParameter,
        Dcm_NegativeResponseCodeType ErrorCode,
        Std_ReturnType  ret);

static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2FServiceDidCallReadAPI(
        Dcm_OpStatusType OpStatus,
        P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData,
        P2VAR(uint8, AUTOMATIC, DCM_VAR_NOINIT) pControlStatusRecord,
        P2VAR(Dcm_NegativeResponseCodeType,AUTOMATIC,DCM_VAR) pNrc);

static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2FServiceDidCallAPI(
        Dcm_OpStatusType OpStatus,
        P2CONST(Dcm_DspDidSignalType,TYPEDEF,DCM_CONST)pDcmDspDidSignal,
        uint16 InputDataOffset,
        uint16    InputDidSize,
        uint16  Offset,
        uint8   MsgCtrlId,
        uint8   InputOutControlParameter,
        P2CONST(Dcm_DspDidControlType, AUTOMATIC, DCM_APPL_CONST)pDspDidControl,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ControlStatusRecordSize,
        P2VAR(Dcm_NegativeResponseCodeType,AUTOMATIC,DCM_VAR) ErrorCode);

static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2FServiceDidSessionAndSecutityCheck(
        uint8 ProtocolCtrlId,
        P2CONST(Dcm_DspDidControlType, AUTOMATIC, DCM_APPL_CONST)pDspDidControl);


static Std_ReturnType  DspInternalUDS0x2F_DidCheck(
        uint16 RecDid,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)pDidCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc);

static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2FServiceConditionCheck(
        uint8 ProtocolCtrlId,
        uint8 MsgCtrlId);
        
/********************************/
#if (DCM_DSP_DID_FOR_2F_NUM > 0)
#define  DCM_START_SEC_VAR_POWER_ON_INIT_16BIT
#include "Dcm_MemMap.h"
static uint16 DcmOnControlDidfor2F[DCM_DSP_DID_FOR_2F_NUM] = {0};
#define  DCM_STOP_SEC_VAR_POWER_ON_INIT_16BIT
#include "Dcm_MemMap.h"

#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(void, DCM_CODE)  Dcm_UDS0x2FCheckNewSession(Dcm_SesCtrlType NewSes)
{
    boolean Support = FALSE;
    uint8   ProtocolCtrlIdIndex;
    uint8  SidTabId;
    uint8  Service_Num;
    uint16 SidTabIndex;
    uint16 ServiceIndex;
    uint8  SesIndex;
    uint8  iloop;
    uint16 DidIndex;
    uint8  SingalIndex;
    Dcm_NegativeResponseCodeType ErrorCode;

    for (ProtocolCtrlIdIndex = 0;
         (ProtocolCtrlIdIndex < Dcm_Cfg.pDcmDsdCfg->DcmDsdServiceTable_Num)
          &&(FALSE == Support); ProtocolCtrlIdIndex++)
    {
        SidTabId  =
        (Dcm_DslCfg.pDcmDslProtocol->pDcmDslProtocolRow)[ProtocolCtrlIdIndex].
        DcmDslServiceTableID;
        /*find SidTabId configuration position in the service configuration table*/
        for(SidTabIndex=0;
           (SidTabIndex<Dcm_DsdCfg.DcmDsdServiceTable_Num)
             &&(FALSE == Support);SidTabIndex++)
        {
            if(SidTabId ==
            ((Dcm_DsdCfg.pDcmDsdServiceTable)[SidTabIndex].DcmDsdSidTabId))
            {
                Service_Num = (Dcm_DsdCfg.pDcmDsdServiceTable)[SidTabIndex].
                        DcmDsdSidTab_ServiceNum;
                for(ServiceIndex=0;(ServiceIndex<Service_Num)
                &&(FALSE==Support);ServiceIndex++)
                {
                    if(0x2Fu == ((Dcm_DsdCfg.pDcmDsdServiceTable)[SidTabIndex].
                            pDcmDsdService[ServiceIndex].DcmDsdServiceId))
                    {
                        for (SesIndex = 0;
                        (SesIndex < ((Dcm_DsdCfg.pDcmDsdServiceTable)[SidTabIndex].
                        pDcmDsdService[ServiceIndex].DcmDsdSessionLevel_Num))
                        && (Support == FALSE); SesIndex++)
                        {
                            if (NewSes == (Dcm_DsdCfg.pDcmDsdServiceTable)[SidTabIndex].
                             pDcmDsdService[ServiceIndex].pDcmDsdSessionLevelRef[SesIndex])
                            {
                                Support = TRUE;
                            }
                        }
                    }
                }
            }
        }
    }

    if ((DCM_DEFAULT_SESSION == NewSes) || (Support == FALSE))
    {
        for (iloop = 0; iloop < DCM_DSP_DID_FOR_2F_NUM; iloop++)
        {
            if (DcmOnControlDidfor2F[iloop] != 0u)
            {
                for (DidIndex = 0;
                    DidIndex < Dcm_DspCfg.DcmDspDidNum; DidIndex++)
                {
                    if (DcmOnControlDidfor2F[iloop]
                       == Dcm_DspCfg.pDcmDspDid[DidIndex].DcmDspDidId)
                    {
                        for (SingalIndex = 0;
                        SingalIndex < Dcm_DspCfg.pDcmDspDid->
                        DcmDspDidSignalNum; SingalIndex++)
                        {
                            if (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                pDcmDspDidData->DcmDspDataUsePort == USE_ECU_SIGNAL)
                            {

                                if (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                        pDcmDspDidData->DcmDspDataEcuSignalFnc != NULL_PTR)
                                {
                                    Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataEcuSignalFnc(
                                            DCM_UDS0X2F_RETURNCONTROLTOECU,
                                            0xFF);
                                }
                            }
                            else if ((Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_SYNCH_FNC)
                                    || (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_FNC)
                                    || (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_FNC_ERROR)
                                    ||(Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_SYNCH_CLIENT_SERVER)
                                    || (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_CLIENT_SERVER)
                                    || (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_CLIENT_SERVER_ERROR))
                            {
                                if (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataReturnControlToECUFnc != NULL_PTR)
                                {
                                    Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataReturnControlToECUFnc(NULL_PTR,
                                                                                    NULL_PTR,
                                                                                    &ErrorCode);
                                }
                            }
                            else
                            {
                                /*idle*/
                            }
                        }
                    }
                }
                DcmOnControlDidfor2F[iloop] = 0;
            }
        }
    }
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(void, DCM_CODE)  Dcm_UDS0x2FCheckNewSecurity(Dcm_SecLevelType  NewSec)
{
    boolean Support = FALSE;
    uint8   ProtocolCtrlIdIndex;
    uint8  SidTabId;
    uint8  Service_Num;
    uint16 SidTabIndex;
    uint16 ServiceIndex;
    uint8  SesIndex;
    uint8  iloop;
    uint16 DidIndex;
    uint8  SingalIndex;
    Dcm_NegativeResponseCodeType ErrorCode;

    for (ProtocolCtrlIdIndex = 0; (ProtocolCtrlIdIndex < Dcm_Cfg.
        pDcmDsdCfg->DcmDsdServiceTable_Num)&&(FALSE == Support);
        ProtocolCtrlIdIndex++)
    {
        SidTabId
        = (Dcm_DslCfg.pDcmDslProtocol->pDcmDslProtocolRow)[ProtocolCtrlIdIndex].
                DcmDslServiceTableID;
        /*find SidTabId configuration position in the service configuration table*/
        for(SidTabIndex=0;
                (SidTabIndex<Dcm_DsdCfg.DcmDsdServiceTable_Num)
                        &&(FALSE == Support);SidTabIndex++)
        {
            if(SidTabId ==
             ((Dcm_DsdCfg.pDcmDsdServiceTable)[SidTabIndex].DcmDsdSidTabId))
            {
                Service_Num = (Dcm_DsdCfg.pDcmDsdServiceTable)[SidTabIndex].
                        DcmDsdSidTab_ServiceNum;
                for(ServiceIndex=0;
                (ServiceIndex<Service_Num)&&(FALSE==Support);
                ServiceIndex++)
                {
                    if(0x2Fu == ((Dcm_DsdCfg.pDcmDsdServiceTable)[SidTabIndex].
                            pDcmDsdService[ServiceIndex].DcmDsdServiceId))
                    {
                        for (SesIndex = 0;
                        (SesIndex < ((Dcm_DsdCfg.pDcmDsdServiceTable)[SidTabIndex].
                        pDcmDsdService[ServiceIndex].DcmDsdSecurityLevel_Num))
                        && (Support == FALSE); SesIndex++)
                        {
                            if (NewSec == (Dcm_DsdCfg.pDcmDsdServiceTable)[SidTabIndex].
                               pDcmDsdService[ServiceIndex].pDcmDsdSecurityLevelRef[SesIndex])
                            {
                                Support = TRUE;
                            }
                        }
                    }
                }
            }
        }
    }

    if (Support == FALSE)
    {
        for (iloop = 0; iloop < DCM_DSP_DID_FOR_2F_NUM; iloop++)
        {
            if (DcmOnControlDidfor2F[iloop] != 0u)
            {
                for (DidIndex = 0;
                     DidIndex < Dcm_DspCfg.DcmDspDidNum;
                     DidIndex++)
                {
                    if (DcmOnControlDidfor2F[iloop]
                        == Dcm_DspCfg.pDcmDspDid[DidIndex].DcmDspDidId)
                    {
                        for (SingalIndex = 0;
                        SingalIndex < Dcm_DspCfg.pDcmDspDid->DcmDspDidSignalNum;
                        SingalIndex++)
                        {
                            if (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                pDcmDspDidData->DcmDspDataUsePort == USE_ECU_SIGNAL)
                            {
                                if (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataEcuSignalFnc != NULL_PTR)
                                {
                                    Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataEcuSignalFnc(
                                            DCM_UDS0X2F_RETURNCONTROLTOECU,
                                            0xFF);
                                }
                            }
                            else if ((Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_SYNCH_FNC)
                                    || (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_FNC)
                                    || (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_FNC_ERROR)
                                    ||(Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_SYNCH_CLIENT_SERVER)
                                    || (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_CLIENT_SERVER)
                                    || (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_CLIENT_SERVER_ERROR))
                            {
                                if (Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataReturnControlToECUFnc != NULL_PTR)
                                {
                                    Dcm_DspCfg.pDcmDspDid->pDcmDspDidSignal[SingalIndex].
                                    pDcmDspDidData->DcmDspDataReturnControlToECUFnc(NULL_PTR,
                                                                                    NULL_PTR,
                                                                                    &ErrorCode);
                                }
                            }
                            else
                            {
                                /*idle*/
                            }
                        }
                    }
                }
                DcmOnControlDidfor2F[iloop] = 0;
            }
        }
    }
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(void, DCM_CODE)Dcm_UdsIOControlSendResponse(
        uint8     ProtocolCtrlId,
        uint8   MsgCtrlId,
        uint16  RecDid,
        uint16  Offset,
        uint16   ControlStatusRecordSize,
        uint8   InputOutControlParameter,
        Dcm_NegativeResponseCodeType ErrorCode,
        Std_ReturnType  ret)
{
    switch(ret)
    {
        case  E_OK:
            SchM_Enter_Dcm(Dcm_Channel);
            Dcm_Channel[Offset] = 0x6F;
            /*response SID*/
            Dcm_Channel[Offset + 1u] = (uint8)(RecDid >> 8u);
            /*response Did MSB*/
            Dcm_Channel[Offset + 2u] = (uint8)RecDid;
            /*response Did LSB*/
            Dcm_Channel[Offset + 3u] = InputOutControlParameter;
            /*InputOutControlParameter*/
            SchM_Exit_Dcm(Dcm_Channel);
            SchM_Enter_Dcm(Dcm_MsgCtrl);
            Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResMaxDataLen
            = 4u + (uint32)ControlStatusRecordSize;
            Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResDataLen
            = 4u + (uint32)ControlStatusRecordSize;
            Dcm_MsgCtrl[MsgCtrlId].MsgContext.pResData
            = &Dcm_Channel[Offset];
            SchM_Exit_Dcm(Dcm_MsgCtrl);
            DsdInternal_ProcessingDone(ProtocolCtrlId);
            break;
        case  E_NOT_OK:
            (void)DsdInternal_SetNrc(ProtocolCtrlId, ErrorCode);
            DsdInternal_ProcessingDone(ProtocolCtrlId);
            break;
        case DCM_E_PENDING:
               Dcm_MsgCtrl[MsgCtrlId].Dcm_OpStatus = DCM_PENDING;
            break;
        default:
            /*NRC=0x22*/
            (void)DsdInternal_SetNrc(ProtocolCtrlId, DCM_E_CONDITIONSNOTCORRECT);
            DsdInternal_ProcessingDone(ProtocolCtrlId);
            break;
    }
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
/********************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2FServiceDidCallReadAPI(
        Dcm_OpStatusType OpStatus,
        P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData,
        P2VAR(uint8, AUTOMATIC, DCM_VAR_NOINIT) pControlStatusRecord,
        P2VAR(Dcm_NegativeResponseCodeType,AUTOMATIC,DCM_VAR) pNrc)
{
    Std_ReturnType ret = E_NOT_OK;
    if (NULL_PTR == pDspDidData->DcmDspDataReadFnc)
    {
        /*DcmDspDataReadFnc is NULL,send NRC 0x22*/
        *pNrc = DCM_E_CONDITIONSNOTCORRECT;
        return E_NOT_OK;
    }
    else if ((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
        || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
    {
        ret = pDspDidData->DcmDspDataReadFnc(
                DCM_INVALID_UINT8,
                pControlStatusRecord,
                NULL_PTR);
    }
    else if ((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
        || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
    {
        ret = pDspDidData->DcmDspDataReadFnc(
                OpStatus,
                pControlStatusRecord,
                NULL_PTR);
    }
    else if ((USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
        || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
    {
        ret = pDspDidData->DcmDspDataReadFnc(
                OpStatus,
                pControlStatusRecord,
                pNrc);
    }
    else
    {
    }
    return ret;
}

#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2FServiceDidCallAPI(
        Dcm_OpStatusType OpStatus,
        P2CONST(Dcm_DspDidSignalType,TYPEDEF,DCM_CONST)pDcmDspDidSignal,
        uint16 InputDataOffset,
        uint16    InputDidSize,
        uint16  Offset,
        uint8   MsgCtrlId,
        uint8   InputOutControlParameter,
        P2CONST(Dcm_DspDidControlType, AUTOMATIC, DCM_APPL_CONST)pDspDidControl,
        P2VAR(uint16, AUTOMATIC, AUTOMATIC)ControlStatusRecordSize,
        P2VAR(Dcm_NegativeResponseCodeType,AUTOMATIC,DCM_VAR) ErrorCode)
{
    EcuSignalDataType SignalValue;
    Std_ReturnType ret = E_NOT_OK;
    P2VAR(uint8, AUTOMATIC, DCM_VAR_NOINIT) pControlEnableMaskRecord = NULL_PTR;
    P2VAR(uint8, AUTOMATIC, DCM_VAR_NOINIT) pControlOptionRecord = NULL_PTR;
    P2VAR(uint8, AUTOMATIC, DCM_VAR_NOINIT) pControlStatusRecord = NULL_PTR;

    if (pDcmDspDidSignal->pDcmDspDidData->DcmDspDataUsePort == USE_ECU_SIGNAL)
    {
        SignalValue = Dcm_MsgCtrl[MsgCtrlId].MsgContext.
                pReqData[4u + InputDataOffset];
        if (pDcmDspDidSignal->pDcmDspDidData->DcmDspDataEcuSignalFnc
                != NULL_PTR)
        {/* SWS_Dcm_00580 */
            pDcmDspDidSignal->pDcmDspDidData->
            DcmDspDataEcuSignalFnc(InputOutControlParameter,SignalValue);
        }
    }
    else if ((pDcmDspDidSignal->pDcmDspDidData->DcmDspDataUsePort == USE_DATA_SYNCH_FNC)
            || (pDcmDspDidSignal->pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_FNC)
            || (pDcmDspDidSignal->pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_FNC_ERROR)
            ||(pDcmDspDidSignal->pDcmDspDidData->DcmDspDataUsePort == USE_DATA_SYNCH_CLIENT_SERVER)
            || (pDcmDspDidSignal->pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_CLIENT_SERVER)
            || (pDcmDspDidSignal->pDcmDspDidData->DcmDspDataUsePort == USE_DATA_ASYNCH_CLIENT_SERVER_ERROR))
    {
        if (0u != pDspDidControl->DcmDspDidControlMaskSize)
        {
            pControlEnableMaskRecord = &(Dcm_MsgCtrl[MsgCtrlId].
                    MsgContext.pReqData[4u + InputDidSize]);
        }
        if (0u != InputDidSize)
        {
            pControlStatusRecord = &Dcm_Channel[Offset + 4u];
        }
        switch (InputOutControlParameter)
        {
            case DCM_UDS0X2F_RETURNCONTROLTOECU:/*ReturnControlToEcu*/
                if (pDcmDspDidSignal->pDcmDspDidData->
                        DcmDspDataReturnControlToECUFnc != NULL_PTR)
                {
                    ret = pDcmDspDidSignal->pDcmDspDidData->
                          DcmDspDataReturnControlToECUFnc(pControlOptionRecord,
                                                            pControlEnableMaskRecord,
                                                            ErrorCode);
                    if (ret == E_OK)
                    {
                        ret = Dcm_Uds0x2FServiceDidCallReadAPI(OpStatus,
                                                        pDcmDspDidSignal->pDcmDspDidData,
                                                        pControlStatusRecord,
                                                        ErrorCode);
                    }
                }
                break;
            case DCM_UDS0X2F_RESETTODEFAULT: /*ResetToDefault*/
                if (pDspDidControl->DcmDspDidResetToDefault == TRUE)
                {
                    if (pDcmDspDidSignal->pDcmDspDidData->DcmDspDataResetToDefaultFnc
                            != NULL_PTR)
                    {
                        ret = pDcmDspDidSignal->pDcmDspDidData->
                                DcmDspDataResetToDefaultFnc(pControlOptionRecord,
                                                            pControlEnableMaskRecord,
                                                            ErrorCode);
                        if (ret == E_OK)
                        {
                            ret = Dcm_Uds0x2FServiceDidCallReadAPI(OpStatus,
                                                            pDcmDspDidSignal->pDcmDspDidData,
                                                            pControlStatusRecord,
                                                            ErrorCode);
                        }
                    }
                }
                else
                {
                    ret = E_NOT_OK;
                    *ErrorCode = DCM_E_REQUESTOUTOFRANGE; /*NRC=0x31*/
                }
                break;
            case DCM_UDS0X2F_FREEZECURRENTSTATE: /*FreezeCurrentState*/
                if (pDspDidControl->DcmDspDidFreezeCurrentState == TRUE)
                {
                    if (pDcmDspDidSignal->pDcmDspDidData->DcmDspDataFreezeCurrentStateFnc
                            != NULL_PTR)
                    {
                        ret = pDcmDspDidSignal->pDcmDspDidData->
                                DcmDspDataFreezeCurrentStateFnc(pControlOptionRecord,
                                                                pControlEnableMaskRecord,
                                                                ErrorCode);
                        if (ret == E_OK)
                        {
                            ret = Dcm_Uds0x2FServiceDidCallReadAPI(OpStatus,
                                                            pDcmDspDidSignal->pDcmDspDidData,
                                                            pControlStatusRecord,
                                                            ErrorCode);
                        }
                    }
                }
                else
                {
                    ret = E_NOT_OK;
                    *ErrorCode = DCM_E_REQUESTOUTOFRANGE; /*NRC=0x31*/
                }
                break;
            case DCM_UDS0X2F_SHORTTERMADJUSTMENT:/*ShortTermAdjustment*/
                if (0u != pDcmDspDidSignal->pDcmDspDidData->DcmDspDataSize)
                {
                    pControlOptionRecord = &(Dcm_MsgCtrl[MsgCtrlId].
                            MsgContext.pReqData[4u + InputDataOffset]);
                }
                if (pDspDidControl->DcmDspDidShortTermAdjustement == TRUE)
                {
                    if (pDcmDspDidSignal->pDcmDspDidData->DcmDspDataShortTermAdjustmentFnc
                            != NULL_PTR)
                    {
                        ret = pDcmDspDidSignal->pDcmDspDidData->
                                DcmDspDataShortTermAdjustmentFnc(pControlOptionRecord,
                                                                pControlEnableMaskRecord,
                                                                ErrorCode);
                        if (ret == E_OK)
                        {
                            ret = Dcm_Uds0x2FServiceDidCallReadAPI(OpStatus,
                                                            pDcmDspDidSignal->pDcmDspDidData,
                                                            pControlStatusRecord,
                                                            ErrorCode);
                        }
                    }
                }
                else
                {
                    ret = E_NOT_OK;
                    *ErrorCode = DCM_E_REQUESTOUTOFRANGE; /*NRC=0x31*/
                }
                break;
            default:
                ret = E_NOT_OK;
                *ErrorCode = DCM_E_REQUESTOUTOFRANGE; /*NRC=0x31*/
                break;
        }
        (*ControlStatusRecordSize) +=
                ((pDcmDspDidSignal->pDcmDspDidData->DcmDspDataSize + 7u) >> 3u);
    }
    else
    {}
    return ret;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
/********************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2FServiceDidSessionAndSecutityCheck(
        uint8 ProtocolCtrlId,
        P2CONST(Dcm_DspDidControlType, AUTOMATIC, DCM_APPL_CONST)pDspDidControl)
{
#if( (STD_ON==DCM_SESSION_FUNC_ENABLED)||(STD_ON == DCM_SECURITY_FUNC_ENABLED) )
    boolean Flag;
    uint8   Index;
#endif
#if(STD_ON == DCM_SESSION_FUNC_ENABLED)
    uint8   SesRefNum;
#endif
#if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
    uint8   SecRefNum;
#endif
    Std_ReturnType  ret = E_OK;

    /*****************************************/
    /*check the current session*/
#if(STD_ON == DCM_SESSION_FUNC_ENABLED)
    /*session check*/
    Flag = FALSE;
    SesRefNum = pDspDidControl->DcmDspDidControlSessionRefNum;
    if (SesRefNum != 0u)
    {
        for (Index = 0; (Index < SesRefNum) && (FALSE == Flag); Index++)
        {
            if (Dcm_MkCtrl.Dcm_ActiveSes
                    == (pDspDidControl->pDcmDspDidControlSessionRow)[Index])
            {
                Flag = TRUE;
            }
        }
        if (FALSE == Flag)
        {
            /*if the processing is not
             * supported in current session,send NRC 0x7F SWS_Dcm_00566*/
            (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
            DsdInternal_ProcessingDone(ProtocolCtrlId);
            return  E_NOT_OK;
        }
    }
#endif

    /*****************************************/
    /*check the current security level*/
#if (STD_ON == DCM_SECURITY_FUNC_ENABLED)
    Flag = FALSE;
    SecRefNum = pDspDidControl->DcmDspDidControlSecurityLevelRefNum;
    if (SecRefNum != 0u)
    {
        for (Index = 0; (Index < SecRefNum) && (FALSE == Flag); Index++)
        {
            if(Dcm_MkCtrl.Dcm_ActiveSec
                    == (pDspDidControl->pDcmDspDidControlSecurityLevelRow)[Index])
            {
                Flag = TRUE;
            }
        }
        if (FALSE == Flag)
        {
            /*if the processing is not supported in
             * current security level,send NRC 0x33 SWS_Dcm_00567 */
            (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_SECURITYACCESSDENIED);
            DsdInternal_ProcessingDone(ProtocolCtrlId);
            return  E_NOT_OK;
        }
    }
#endif

    return ret;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/***************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static Std_ReturnType  DspInternalUDS0x2F_DidCheck(
        uint16 RecDid,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)pDidCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    uint8     Index;
    boolean   Flag = FALSE;
    Std_ReturnType  ret = E_NOT_OK;

    /*find the corresponding DID in configuration*/
    for (Index = 0; (Index < Dcm_DspCfg.DcmDspDidNum) && (FALSE == Flag); Index++)
    {
        /*single did check*/
        if ((RecDid == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId)
        &&(TRUE == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidUsed))/* SWS_Dcm_00564 */
        {
            Flag = TRUE;
            (*pDidCfgIndex) = Index;
            ret = E_OK;
        }
    }
    if (E_NOT_OK == ret)
    {
        /*if not found,send NRC 0x31*/
        (*pNrc) = DCM_E_REQUESTOUTOFRANGE;
    }

    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/***************************/
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2FServiceConditionCheck(
        uint8 ProtocolCtrlId,
        uint8 MsgCtrlId)
{
    Std_ReturnType ret;

    /*************************************************/
    #if(STD_ON == DCM_SESSION_FUNC_ENABLED)
    /*session check,check whether the current
     *  session supports the request service*/
    ret = DsdInternal_SesCheck(ProtocolCtrlId,
            SID_INPUT_OUTPUT_CONTROL_BY_IDENTIFIER);
    if(E_NOT_OK == ret)
    {
        /****@req DCM-FUNR-073[DCM211]****/
        /*the current session does not support
         *  the request service,send NRC = 0x7F*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,
                DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
    #endif

    /*************************************************/
    #if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
    /*security check,check whether the current
     *  security supports the request service*/
    ret = DsdInternal_SecurityCheck(ProtocolCtrlId,
            SID_INPUT_OUTPUT_CONTROL_BY_IDENTIFIER);
    if (E_NOT_OK == ret)
    {
        /****@req DCM-FUNR-074[DCM217]****/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,
                DCM_E_SECURITYACCESSDENIED); /*NRC = 0x33*/
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
    #endif
    /*min-length check*/
    if (DCM_UDS0X2F_REQ_DATA_MINLENGTH
            > Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen)
    {
       /*the length of massage is not correct,send NRC 0x13*/
       (void)DsdInternal_SetNrc(ProtocolCtrlId,
               DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
       DsdInternal_ProcessingDone(ProtocolCtrlId);
       return E_NOT_OK;
    }
    return E_OK;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

/****************************/
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(Std_ReturnType, DCM_CODE)Dcm_UDS0x2F(
        Dcm_OpStatusType OpStatus,
        uint8  ProtocolCtrlId,
        P2VAR(Dcm_NegativeResponseCodeType,AUTOMATIC,DCM_VAR) ErrorCode)
{
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
    uint16    RecDid;
    uint16    InputDidSize = 0;
    uint32    Mask = 0;
    uint16    InputDataOffset = 0;
    uint16    Offset;
    uint8     DidCfgIndex;
    uint8     DidInfoCfgIndex;
    uint8     TxChannelCtrlIndex;
    uint8     TxChannelCfgIndex;
    uint16    ControlStatusRecordSize = 0;
    uint8     InputOutControlParameter;
    uint8     Postion = 0;
    P2CONST(Dcm_DspDidControlType ,AUTOMATIC ,DCM_APPL_CONST) pDspDidControl;
    P2CONST(Dcm_DspDidSignalType,TYPEDEF,DCM_CONST)pDcmDspDidSignal = NULL_PTR;
    uint8 iloop;
#endif
    uint8     MsgCtrlId;
    Std_ReturnType ret;

   /*if the required protocol is configured,get the index of runtime datum*/
    MsgCtrlId =  Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex;

    /*************************************************/
    ret = Dcm_Uds0x2FServiceConditionCheck(ProtocolCtrlId, MsgCtrlId);
    if(E_OK != ret)
    {
        return ret;
    }

#if (STD_OFF == DCM_DSP_DID_FUNC_ENABLED)
    /*NRC 0x31:request out of range*/
    (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
    DsdInternal_ProcessingDone(ProtocolCtrlId);
    return E_NOT_OK;

#else

    /**************************************************/
    /*get the required DID from request message*/
    RecDid = (uint16)((uint16)((uint16)Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[1u]) << 8u)\
            |((uint16) Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[2u]);

    /*Determine if the DID is configured SWS_Dcm_00563*/
    ret = DspInternalUDS0x2F_DidCheck(
             RecDid,
             &DidCfgIndex,
             ErrorCode);
    if(E_NOT_OK == ret)
    {
        /*if not found,send NRC 0x31*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return  E_NOT_OK;
    }

    /**************************************************/
    DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidInfoIndex;

    /*check whether the Did can be configured SWS_Dcm_00565 */
    pDspDidControl = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidControl;
    if (NULL_PTR == pDspDidControl)
    {
        /*if the Did can be dynamically defined,send NRC 0x31*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return  E_NOT_OK;
    }
    ret = Dcm_Uds0x2FServiceDidSessionAndSecutityCheck(ProtocolCtrlId, pDspDidControl);
    if(E_OK != ret)
    {
        return ret;
    }

    /*check inputOutputControlParameter is supported*/
    InputOutControlParameter = Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[3u];
    if (InputOutControlParameter > 3u)
    {
        /*if inputOutputControlParameter is not supported,send NRC 0x31*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return  E_NOT_OK;
    }

    /*Calculate the InputDidSize*/
    if ((Dcm_DspCfg.pDcmDspDid)[DidCfgIndex].pDcmDspDidSignal != NULL_PTR)
    {
        pDcmDspDidSignal = (Dcm_DspCfg.pDcmDspDid)[DidCfgIndex].pDcmDspDidSignal;
        for (iloop = 0;
                iloop < (Dcm_DspCfg.pDcmDspDid)[DidCfgIndex].DcmDspDidSignalNum;
                iloop++)
        {
            InputDidSize +=
                    ((pDcmDspDidSignal->pDcmDspDidData->DcmDspDataSize + 7u) >> 3u);
            pDcmDspDidSignal++;
        }
    }

    /*configuration check*/
    if ((pDspDidControl->DcmDspDidControlMask != DCM_CONTROLMASK_NO)
        && ((pDcmDspDidSignal->pDcmDspDidData->DcmDspDataUsePort
                ==  USE_DATA_SENDER_RECEIVER)
                || (pDcmDspDidSignal->pDcmDspDidData->DcmDspDataUsePort
                        ==  USE_DATA_SENDER_RECEIVER_AS_SERVICE)))
    {
        /* SWS_Dcm_01273,send NRC 0x13*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,
                DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return  E_NOT_OK;
    }

    if ((pDspDidControl->DcmDspDidControlMask == DCM_CONTROLMASK_NO)
            && (pDspDidControl->DcmDspDidControlMaskSize != 0u))
    {
        /* SWS_Dcm_01274,send NRC 0x13*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,
                DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return  E_NOT_OK;
    }

    /*Calculate the Mask*/
    for (iloop = 0; iloop < pDspDidControl->DcmDspDidControlMaskSize; iloop++)
    {
        Mask = Mask << 8u;
        Mask |= (uint32)(Dcm_MsgCtrl[MsgCtrlId].MsgContext.
                pReqData[4u + InputDidSize + (uint16)iloop]);
    }

    /*total length check*/
    if (((Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen
            != (uint32)((uint32)((uint32)4UL + InputDidSize + pDspDidControl->DcmDspDidControlMaskSize)))
                && (InputOutControlParameter == DCM_UDS0X2F_SHORTTERMADJUSTMENT))
        || ((Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen
                != (uint32)((uint32)((uint32)4UL + pDspDidControl->DcmDspDidControlMaskSize)))
                && (InputOutControlParameter != DCM_UDS0X2F_SHORTTERMADJUSTMENT)))
    {
           /*the length of massage is not correct,send NRC 0x13*/
           (void)DsdInternal_SetNrc(ProtocolCtrlId,
                   DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
           DsdInternal_ProcessingDone(ProtocolCtrlId);
           return E_NOT_OK;
    }

    /*****************************************/
    /*find the TX buffer*/
    TxChannelCtrlIndex = Dcm_MsgCtrl[MsgCtrlId].Dcm_TxCtrlChannelIndex;
    TxChannelCfgIndex  = Dcm_ChannelCtrl[TxChannelCtrlIndex].Dcm_ChannelCfgIndex;
    Offset = (Dcm_DslCfg.pDcmChannelCfg)[TxChannelCfgIndex].offset;

    if ((Dcm_DspCfg.pDcmDspDid)[DidCfgIndex].DcmDspDidSignalNum > 1u)
    {
        if ((Dcm_DspCfg.pDcmDspDid)[DidCfgIndex].pDcmDspDidSignal != NULL_PTR)
        {
            pDcmDspDidSignal =
                    (Dcm_DspCfg.pDcmDspDid)[DidCfgIndex].pDcmDspDidSignal;
            for (iloop = 0;
                    iloop < (Dcm_DspCfg.pDcmDspDid)[DidCfgIndex].DcmDspDidSignalNum;
                    iloop++)
            {
                if (pDspDidControl->DcmDspDidControlMask == DCM_CONTROLMASK_INTERNAL)
                {/* SWS_Dcm_00581 */
                    if (pDspDidControl->DcmDspDidControlEnableMask != NULL_PTR)
                    {
                        Postion = pDspDidControl->DcmDspDidControlEnableMask->
                                DcmDspDidControlMaskBitPosition;
                    }
                    else
                    {
                        if (pDspDidControl->DcmDspDidControlMaskSize == 1u)
                        {
                            Postion = 8u;
                        }
                        else if (pDspDidControl->DcmDspDidControlMaskSize == 2u)
                        {
                            Postion = 16u;
                        }
                        else if (pDspDidControl->DcmDspDidControlMaskSize == 3u)
                        {
                            Postion = 24u;
                        }
                        else if (pDspDidControl->DcmDspDidControlMaskSize == 4u)
                        {
                            Postion = 32u;
                        }
                        else
                        {
                            /*idle*/
                        }
                    }
                    if ((Mask & (uint32)((uint32)((uint32)0x01u << (Postion - iloop)))) != 0UL)
                    {
                        ret = Dcm_Uds0x2FServiceDidCallAPI(OpStatus,
                                                            pDcmDspDidSignal,
                                                            InputDataOffset,
                                                            InputDidSize,
                                                            Offset,
                                                            MsgCtrlId,
                                                            InputOutControlParameter,
                                                            pDspDidControl,
                                                            &ControlStatusRecordSize,
                                                            ErrorCode);
                    }
                }
                else if (pDspDidControl->DcmDspDidControlMask == DCM_CONTROLMASK_EXTERNAL)
                {/* SWS_Dcm_01272 */
                    ret = Dcm_Uds0x2FServiceDidCallAPI(OpStatus,
                                                        pDcmDspDidSignal,
                                                        InputDataOffset,
                                                        InputDidSize,
                                                        Offset,
                                                        MsgCtrlId,
                                                        InputOutControlParameter,
                                                        pDspDidControl,
                                                        &ControlStatusRecordSize,
                                                        ErrorCode);
                }
                else
                {}
                InputDataOffset +=
                        ((pDcmDspDidSignal->pDcmDspDidData->DcmDspDataSize + 7u) >> 3u);
                pDcmDspDidSignal++;
            }
        }
        else
        {
            /*if pDcmDspDidSignal is not supported,send NRC 0x22*/
            (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_CONDITIONSNOTCORRECT);
            DsdInternal_ProcessingDone(ProtocolCtrlId);
            return  E_NOT_OK;
        }
    }
    else if ((Dcm_DspCfg.pDcmDspDid)[DidCfgIndex].DcmDspDidSignalNum == 1u)
    {
        pDcmDspDidSignal = (Dcm_DspCfg.pDcmDspDid)[DidCfgIndex].pDcmDspDidSignal;
        ret = Dcm_Uds0x2FServiceDidCallAPI(OpStatus,
                                            pDcmDspDidSignal,
                                            InputDataOffset,
                                            InputDidSize,
                                            Offset,
                                            MsgCtrlId,
                                            InputOutControlParameter,
                                            pDspDidControl,
                                            &ControlStatusRecordSize,
                                            ErrorCode);
    }
    else
    {
        /*if DcmDspDidSignalNum is 0,send NRC 0x22*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_CONDITIONSNOTCORRECT);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return  E_NOT_OK;
    }

#if (DCM_DSP_DID_FOR_2F_NUM > 0)
    if (InputOutControlParameter != DCM_UDS0X2F_RETURNCONTROLTOECU)
    { /*store the control DID*/
        for (iloop = 0; iloop < DCM_DSP_DID_FOR_2F_NUM; iloop++)
        {
            if (DcmOnControlDidfor2F[iloop] == 0u)
            {
                DcmOnControlDidfor2F[iloop] = RecDid;
                break;
            }
        }
    }
    else
    { /*clear the control DID*/
        for (iloop = 0; iloop < DCM_DSP_DID_FOR_2F_NUM; iloop++)
        {
            if (DcmOnControlDidfor2F[iloop] == RecDid)
            {
                DcmOnControlDidfor2F[iloop] = 0;
                break;
            }
        }
    }
#endif

    /* send response message */
    Dcm_UdsIOControlSendResponse(    ProtocolCtrlId,
                                    MsgCtrlId,
                                     RecDid,
                                     Offset,
                                    ControlStatusRecordSize,
                                    InputOutControlParameter,
                                    *ErrorCode,
                                    ret);

    return ret;
#endif
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
